STM32: 做一个与ST |
您所在的位置:网站首页 › st-link utility怎么加密 › STM32: 做一个与ST |
ST官方提供了ST-LINK/V2-1调试器的原理图,PCB图及相关的固件更新工具(Stlink Utility或者ST-LINK firmware upgrade)当然也可以通过第三方的工具对调试器进行固件的升级操作(STLinkReflash)。但如果你在使用ST-LINK/V2-1的过程中不慎将原有的固件破环或者是MCU烧毁,使得ST-LINK/V2-1无法正常使用,这时候你就需要一个可用的bootloader进行修复。 -实现一个简单的bootloader, 能够实现固件的下载及加载经过进一个月的分析,不断尝试,自己写一个bootloader实现固件下载更新及加载也是可能的。 完整的固件包含如下这几个部分: Flash size: 128KiB bootloader: 15KiB system parameter: 1KiB firmware: 111KiB manifest: 1KiB -了解固件升级相关的通信协议由于STLinkReflash命令在固件升级过程中,可以显示升级过程中发送及接收的数据的相关内容,并且结合OpenOCD源代码中关于ST-LINK通信相关的代码,可以很容易地猜测出固件升级的流程: STM32: ST-LINK/V2与STLINK/V2-1 DFU协议分析 NOTE: STLinkReflash工具在写入ST-LINK/V2-1的时候,没有去更新固件的配置信息(位于flash 0x08003c00 ~ 0x08003ffff)。这使得如果bootloader不包启配置信息(只包含flash前15KiB的数据),那么通过该工具写入的ST-LINK/V2-1固件是无法使用的(USB无法正常枚举),而必须先通过STLink Utility工具进行固件更新。 加密算法,通过分析STLinkReflash工具,我们知道固件在传送过程中,会进行加密,我们需要相关的加密算法来实现: STM32: 实现Advanced Encryption Standard(AES) – 128-bit加密算法 - 官方原版bootloader有了固件升级相关的通信协议及相关的参考文档,获取官方的bootloader也不是什么难事。 原以为有了ST-LINK/V2-1的固件并且知道固件的起始地址,就可以写一个简单的bootloader加载固件,可事实并非如此(加载JLink固件可以正常运行,但是对于ST-LINK/V2-1的固件,就没有那么走运了),还是需要分析调试bootloader代码,以发现其中的差异: STM32: 从STLinkReflash提取jlink与ST-LINK/V2-1固件 - USB接口实现及其配置 ST-LINK/V2-1通过USB接口与PC机进行通信,在bootloader模式下接口的相关配置信息在linux/ubuntu下可通过lsusb命令查看: $ lsusb -d 0483: -v Bus 001 Device 014: ID 0483:3748 STMicroelectronics ST-LINK/V2 Couldn't open device, some information will be missing Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x0483 STMicroelectronics idProduct 0x3748 ST-LINK/V2 bcdDevice 1.00 iManufacturer 1 iProduct 2 iSerial 3 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 39 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 100mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 3 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 255 Vendor Specific Subclass bInterfaceProtocol 255 Vendor Specific Protocol iInterface 4 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x83 EP 3 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 0有了这些相关信息,我们就可以完成USB接口配置的相关代码了。这里我们会用到EP 1 IN 与 EP 2 OUT而EP 3 IN在ST-LINK进行debug/trace的时候会用到。 -基于ChibiOS/RT v16.1.2的实时系统实现的bootloader1. 系统上电之后会检查固件是否完整,固件完整则跳转执行固件代码否则进入DFU模式: /* * Application entry point. */ int __attribute__((noreturn)) main(void) { /* * System initializations. * - HAL initialization, this also initializes the configured device drivers * and performs the board-specific initializations. */ halInit(); do { uint32_t flashSize, magicValue; /* Check the firmware intergrity */ flashSize = (*(volatile uint32_t *)0x1FFFF7E0 & 0xffff) CSR & RCC_CSR_SFTRSTF) != 0 && BKP->DR1 != 0xfeed) { /* Software reset occurred */ break; } if (BKP->DR1 == 0xfeed) BKP->DR1 = 0x0000; /* Clear reset flag */ RCC->CSR |= RCC_CSR_RMVF; JumpToUserApp(0x08004000); } while (0); /* * System initializations. * - Kernel initialization, the main() function becomes a thread and the * RTOS is active. */ chSysInit(); // ... }NOTE: 这里可以看到固件检查及跳转是在halInit()之后及chSysInit()之前。 2. 跳转时要重新设置线程工作模式: 在特权模式下运行并使用Main Stack: void JumpToUserApp(uint32_t pAppAddr) { volatile uint32_t *pMspAddr; volatile uint32_t *pJmpAddr; /* Get main stack address from the application vector table */ pMspAddr = (volatile uint32_t *)(pAppAddr + 0); /* Get jump address from application vector table */ pJmpAddr = (volatile uint32_t *)(pAppAddr + 4); /* Set stack pointer as in application's vector table */ __set_MSP(*pMspAddr); /* Privileged and using main stack */ __set_CONTROL(0); /* Jump to the new application */ (*(void (*)(void))*pJmpAddr)(); }NOTE: ChibiOS/RT初始化时,会使MCU工作在特权模式下,但使用的stack为thread stack。相关的代码在:os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s /** * @brief Control special register initialization value. * @details The system is setup to run in privileged mode using the PSP * stack (dual stack mode). */ #if !defined(CRT0_CONTROL_INIT) || defined(__DOXYGEN__) #define CRT0_CONTROL_INIT (CONTROL_USE_PSP | \ CONTROL_MODE_PRIVILEGED) #endif // ... Reset_Handler: /* Interrupts are globally masked initially.*/ cpsid i /* PSP stack pointers initialization.*/ ldr r0, =__process_stack_end__ msr PSP, r0 #if CRT0_INIT_FPU == TRUE /* FPU FPCCR initialization.*/ movw r0, #CRT0_FPCCR_INIT & 0xFFFF movt r0, #CRT0_FPCCR_INIT >> 16 movw r1, #SCB_FPCCR & 0xFFFF movt r1, #SCB_FPCCR >> 16 str r0, [r1] dsb isb /* CPACR initialization.*/ movw r0, #CRT0_CPACR_INIT & 0xFFFF movt r0, #CRT0_CPACR_INIT >> 16 movw r1, #SCB_CPACR & 0xFFFF movt r1, #SCB_CPACR >> 16 str r0, [r1] dsb isb /* FPU FPSCR initially cleared.*/ mov r0, #0 vmsr FPSCR, r0 /* FPU FPDSCR initially cleared.*/ movw r1, #SCB_FPDSCR & 0xFFFF movt r1, #SCB_FPDSCR >> 16 str r0, [r1] /* Enforcing FPCA bit in the CONTROL register.*/ movs r0, #CRT0_CONTROL_INIT | CONTROL_FPCA #else movs r0, #CRT0_CONTROL_INIT #endif /* CONTROL register initialization as configured.*/ msr CONTROL, r0 isb // ... -相关源代码这里提供部分代码供参考: https://github.com/brobwind/chibios_bro_dbg_link_v2_1 -预编译固件及己知问题相关的固件可以从这里下载:2016_11_24_BRO-DBG-LINK-V2-1_BL-20161121.bin 己知问题: - 下载ST-LINK/V2-1固件之后,无法再通过Stlink Utility,STLink firmware upgrade和STLinkReflash工具更新固件。 NOTE: 设置volume label可以通过ST-LINK firmware upgrade工具完成,label的最大长度为11字节。 ST-LINK firmware upgrade工具还可以指定固件类型: |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |